﻿using System;
using System.Collections.Generic; 
using System.Timers;
using NTTDATA.BEENChina.CaseMonitor.Base;
using NTTDATA.BEENChina.CaseMonitor.CaseChecker;
using NTTDATA.BEENChina.CaseMonitor.Config;
using NTTDATA.BEENChina.CaseMonitor.DAO;
using NTTDATA.BEENChina.CaseMonitor.Notice;
using NTTDATA.BEENChina.CaseMonitor.ServerChecker;

namespace NTTDATA.BEENChina.CaseMonitor.UI
{
    internal delegate void ShowLog(String message);
    internal delegate void ShowMessage(String serverName, String monitorType, String result, bool call = false);
    internal delegate void ClearMessage();

    public class Monitor
    {
        private System.Timers.Timer timer = new System.Timers.Timer();
        private bool isWork = false;
        //mi
        private int timeSpan = 10;

        private  FormMain formMain;

        private CommuniConfig config;

        private DateTime checkRunningTime;

        public Monitor( FormMain formMain)
        {
           
            this.formMain = formMain;
            checkRunningTime = DateTime.Now;

            loadCounf();
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        }

        private void loadCounf()
        {
            try
            {
                config = CommuniConfig.LoadCommuniConfig();
            }
            catch (Exception ex)
            {
                Log.Console.Error("load config error ",ex);
            }

            if (config != null)
                timeSpan = config.TimeSpan;
          
            timer.Interval = 60 * 1000 ;
           
            

        }

        public void Start()
        {
            timer.Start();
        }

        public void Stop()
        {
            timer.Stop();
        }

        public bool IsCall { get; set; }

        private static object lockobj = new object();

        private void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (lockobj)
            {
                try
                {

             
                    AlarmMessages.GetInstances().ClearMsg();

                    isWork = true;
                
                  

                 //   ClearMsg();

                
                   //List<Task> tasks = new List<Task>();

                    if (config.CaseCheckerFiles.Count > 0)
                    {
                        foreach (string caseCheckerFile in config.CaseCheckerFiles)
                        {
                            //string file = caseCheckerFile;
                            //tasks.Add(Task.Factory.StartNew(() => CheckDataCount(file)));

                            //Thread.Sleep(1000);

                            string file = caseCheckerFile;
                            CheckDataCount(file);
                        }
                    }
                    else
                    {
                        // tasks.Add( Task.Factory.StartNew(() => CheckDataCount(string.Empty)) );
                        CheckDataCount(string.Empty);
                    }

                     

                    if (DateTime.Compare(DateTime.Now, checkRunningTime) > 0)
                    {
                     /*   tasks.Add(Task.Factory.StartNew(() =>
                                                            {
                                                                CheckServerRunning();
                                                                //set next run time
                                                                checkRunningTime = checkRunningTime.AddMinutes(timeSpan);
                                                            }));*/

                        CheckServerRunning();
                        //set next run time
                        checkRunningTime = checkRunningTime.AddMinutes(timeSpan);
                    }


                    //Thread threadCheckCount = new Thread(new ThreadStart(CheckDataCount));
                    //threadCheckCount.Start();

                    //Thread threadCheckRunning = new Thread(new ThreadStart(CheckServerRunning));
                    //threadCheckRunning.Start(); 
                

                   /* Task.WaitAll( tasks.ToArray());

                    foreach (var task in tasks)
                    {
                        task.Dispose();
                    }*/
                    Alarm();
                }
                catch (Exception ex)
                {

                    Log.Console.Error("timmer error",ex);
                }

            }
        }

        private void CheckServerRunning()
        {
            try
            { 
           
                RunningChecker checker = RunningChecker.GetInstance();
                checker.ProcessMessage -= new EventHandler<CheckerEvent>(chk_LogMessage);
                checker.ProcessMessage += new EventHandler<CheckerEvent>(chk_LogMessage);
                List<Server> notes = checker.Check();
                 

                if (notes != null && notes.Count > 0)
                {
                    ShowCheckServerRunningMsg(notes);
                }
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.CheckServerRunning() error", ex);
            }
            
        }

        private void CheckDataCount(string configFile )
        {
            try
            {
                DataCountChecker chk;
                if (string.IsNullOrEmpty(configFile))
                    chk = new DataCountChecker();
                else
                    chk = new DataCountChecker(configFile);

                chk.ProcessMessage -= new EventHandler<CheckerEvent>(chk_LogMessage);
                chk.ProcessMessage += new EventHandler<CheckerEvent>(chk_LogMessage);

                List<Note> notes = chk.Check();
                 

                if (notes != null && notes.Count > 0)
                { 

                    ShowCheckDataMsg(notes);
                }
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.CheckDataCount() error", ex);
            }
        }

        private void chk_LogMessage(object sender, CheckerEvent e)
        {
            try
            {
                CaseDBAccesser.InsertProcessLog("processMsg", "", e.Message);

                if (formMain.IsMonitor)
                {
                    ShowLog showlog = new ShowLog(formMain.MsgFrom.ShowMessage);

                    formMain.MsgFrom.Invoke(showlog, new object[] { e.Message });
                }
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.chk_LogMessage() InsertProcessLog error", ex);
            }
           
        }

        private void ShowCheckDataMsg(List<Note> notes)
        {

            try
            {

            
            String msg = "";
            if (notes != null && notes.Count > 0)
            {
                string warmMsg = string.Empty;
                int indexMsg = 0;

                foreach (var note in notes)
                {
                    msg = String.Format("{0}:{1}", note.Name, note.GetDataCount());

                    foreach (var noteChilds in note.NoteList)
                    {
                        msg += String.Format("->{0}:{1}", noteChilds.Name, noteChilds.GetDataCount());
                    }

                   // AddItem(note.Name, msg);
                   ShowMsg( string.Format("{0}({1})" ,note.Name,note.CustomerID),"CheckDataCount", msg,IsCall );


                   Log.Console.Warn(string.Format("{0}({1}){2}", note.Name, note.CustomerID,msg));
                     

                    AlarmMessages.GetInstances().Messages.Add(string.Format("{0}({1}){2}", note.Name, note.CustomerID, msg));

                } 

            }

            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.ShowCheckDataMsg() error", ex);
            }

        }

        private void ShowCheckServerRunningMsg(List<Server> notes)
        {

            try
            {
          
                
                if (notes != null && notes.Count > 0)
                {
                    
                    //int indexMsg = 0;

                    foreach (var note in notes)
                    {
                     
                        // AddItem(note.Name, msg);
                         ShowMsg(note.Name,"CheckRunning", note.WorkState(), IsCall);
                         
                         Log.Console.Warn(string.Format("{0}{1}", note.Name, note.WorkState()));
                

                         AlarmMessages.GetInstances().Messages.Add(String.Format("{0}:{1}", note.Name, note.WorkState()));

                    } 

              
                }
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.ShowCheckServerRunningMsg() error", ex);

            }
        }

        private ShowMessage showMessage = null;

        private void ShowMsg(String serverName, String monitorType, String result, bool call = false)
        {
            try
            {
                CaseDBAccesser.InsertProcessLog("processLog", serverName, string.Format("{0} . {1}", result, call ? "call Tel ." : ""));

                if (showMessage == null)
                {
                    showMessage = new ShowMessage(formMain.showMessage);
                }

                formMain.Invoke(showMessage, new Object[] { serverName, monitorType, result, IsCall });
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.ShowMsg() error", ex);

            }

        }

        private ClearMessage clearMessage = null;

        private void ClearMsg()
        {
            try
            {
                if (clearMessage == null)
                {
                    clearMessage = new ClearMessage(formMain.ClearMessage);
                }

                formMain.Invoke(clearMessage);
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.ClearMsg() error", ex);

            }

        }

      

        private void Alarm()
        {
            try
            {
                if (IsCall)
                {

                    string warmMsg = string.Empty;

                    if (AlarmMessages.GetInstances().Messages.Count > 0)
                    {
                        for (int i = 0; i < AlarmMessages.GetInstances().Messages.Count; i++)
                        {
                            if (warmMsg.Length > 0)
                                warmMsg += Environment.NewLine;
                            warmMsg += string.Format("{0}.{1}", i + 1, AlarmMessages.GetInstances().Messages[i]);
                        }
                        Alarm(warmMsg);
                    }


                }
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.Alarm() error", ex);

            }
        }

        private void Alarm(String msg)
        {
            String message = msg.Replace(" ","");
            
            Mobile mobile = null; 


            try
            {
                if (config != null && config.CommuniPhones !=null && config.CommuniPhones.Count>0)
                {
                    if (!String.IsNullOrEmpty(config.SerialPort) &&
                         (config.BaudRate > 0))
                    {
                        mobile = new Mobile(config.SerialPort, config.BaudRate);

                        mobile.Notice(config.CommuniPhones,message);
 
                        Log.Console.Warn( string.Format( "send message:{0} to Tel:{1}"
                            ,message
                            ,string.Join(",", config.CommuniPhones)));
                    }

                }
            }
            catch (Exception ex)
            {

                Log.Console.Error("Monitor.Alarm() error", ex);
            }

           
        }

    }
}
